package controllers

import (
    "gouniapp/configs"
	"net/http"
	"github.com/gin-gonic/gin"
	"github.com/samber/lo"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"encoding/json"
	"github.com/google/uuid"
	"strings"
	"errors"
	"log"
	"time"
	"fmt"
)

// 添加或修改行保存数据库
func AddOrupdate(bgsx configs.FormSchema, data map[string]interface{}, tid uint, zdsz map[string]configs.FieldConfig, currentUser *configs.User) (interface{}, int, string) {
    delete(data, "created_at")
    delete(data, "updated_at")
    tx := configs.DB.Begin() // 开启事务
    defer func() {
        if r := recover(); r != nil {
            tx.Rollback()
        }
    }()
    // 预约校验
    if bgsx.IsReservation {
        if code, msg := validateReservation(tx, bgsx, data, tid); code != http.StatusOK {
            tx.Rollback()
            return nil, code, msg
        }
        // 生成排号序号
        date, ok1 := data["reservation_date"].(string)
        start, ok2 := data["slot_start"].(string)
        if !ok1 || !ok2 {
            tx.Rollback()
            return nil, http.StatusInternalServerError, "缺失预约日期或时段信息"
        }
        var maxSeq int
        // 使用FOR UPDATE锁定记录，防止并发冲突
        query := "SELECT COALESCE(MAX(sequence_number), 0) AS max_seq FROM `" + bgsx.TableName + "` WHERE reservation_date = ? AND slot_start = ? FOR UPDATE"
        if err := tx.Raw(query, date, start).Scan(&maxSeq).Error; err != nil {
            tx.Rollback()
            return nil, http.StatusInternalServerError, "获取排号失败: " + err.Error()
        }
        data["sequence_number"] = maxSeq + 1
    } else {
        // 如果不需要预约，直接移除预约字段，防止插入空值报错
        reservationFields := []string{"reservation_date", "slot_start", "slot_end", "sequence_number", "verification_code", "used", "used_time", "operator_id"}
        for _, field := range reservationFields {
            delete(data, field)
        }
    }
    if tid == 0 {
        if err := tx.Table(bgsx.TableName).Create(&data).Error; err != nil {
            log.Printf("业务数据创建失败: %v", err)
            tx.Rollback()
            return nil, http.StatusInternalServerError, StatusCreateFailed
        }
        value, ok := data["@id"].(int64)
        if !ok {
            tx.Rollback()
            return nil, http.StatusInternalServerError, "创建业务数据id未获取到"
        }
        rowid := uint(value)
        // 生成核销码（在创建记录后执行）
		if bgsx.EnableVerification {
			verificationCode := GenerateVerificationCode(bgsx.ID, rowid)
			if verificationCode == "" {
				tx.Rollback()
				return nil, http.StatusInternalServerError, "核销码生成失败"
			}
			if err := tx.Table(bgsx.TableName).Where("id = ?", rowid).Update("verification_code", verificationCode).Error; err != nil {
				tx.Rollback()
				return nil, http.StatusInternalServerError, "核销码更新失败"
			}
			data["verification_code"] = verificationCode
		}
        // 调用新的流程处理方法
        if success, errCode, errMsg := createProcessInstance(tx, bgsx, data, rowid); !success {
            return nil, errCode, errMsg
        }
        commitErr := tx.Commit().Error
        // 在事务提交成功后发送消息
        if commitErr == nil && currentUser != nil {
            go func(userID uint, formName string, recordID uint, dataJSON string) {
                message := fmt.Sprintf("表单「%s」记录 #%d 已创建\n数据内容：%s",formName, recordID,dataJSON)
                configs.CreateMessage(nil, userID, "填报成功", message)
            }(currentUser.ID, bgsx.FormName, rowid, toJSONString(data))
        }
        return data, http.StatusOK, StatusCreateSuccess
    } else {
		var zds []string
		for k := range zdsz {
		    if k != "created_at" && k != "updated_at" && k != "sequence_number" {
			    zds = append(zds, k)
		    }
		}
		if len(zds) == 0 {
		    tx.Rollback()
			return nil, http.StatusInternalServerError, StatusNoFieldsToUpdate
		}
        zds = append(zds, "cjz")
        if err := tx.Table(bgsx.TableName).Select(zds).Where("id = ?", tid).Updates(data).Error; err != nil {
            tx.Rollback()
            return nil, http.StatusInternalServerError, StatusUpdateFailed
        }
        tx.Commit()
        return data, http.StatusOK, StatusUpdateSuccess
	}
}

func generateVerificationCode() string {
    return strings.ToUpper(strings.Replace(uuid.New().String(), "-", "", -1)[0:8])
}

// 预约核销信息查询
func VerifyReservation(c *gin.Context) {
	currentUser := GetCurrentUser(c)
	if currentUser == nil {
		JsonResponse(c, http.StatusUnauthorized, "请先登录", nil)
		return
	}
	var req struct {
		VerifyCode string `json:"code" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		JsonResponse(c, http.StatusBadRequest, "参数格式错误", nil)
		return
	}
	claims, err := ParseVerificationToken(req.VerifyCode)
	if err != nil {
		JsonResponse(c, http.StatusBadRequest, "核销码无效："+err.Error(), nil)
		return
	}
	var form configs.FormSchema
	if err := configs.DB.First(&form, claims.FormID).Error; err != nil {
		JsonResponse(c, http.StatusNotFound, "表单不存在", nil)
		return
	}
	fmt.Println(claims)
	var record map[string]interface{}
	if err := configs.DB.Table(form.TableName).Where("id = ? AND verification_code = ?", claims.RowID, req.VerifyCode).Scan(&record).Error; err != nil {
		JsonResponse(c, http.StatusNotFound, "未找到有效预约记录", nil)
		return
	}
	if used, ok := record["used"].(bool); ok && used {
		JsonResponse(c, http.StatusConflict, "该核销码已被使用", nil)
		return
	}
	var user configs.User
    if err := configs.DB.Where("id = ?", record["cjz"]).First(&user).Error; err != nil {
        JsonResponse(c, http.StatusNotFound, "预约用户不存在", nil)
        return
    }
	JsonResponse(c, http.StatusOK, "可核销", gin.H{
		"username": user.Username,
		"name":     user.Name,
		"date":     record["reservation_date"],
		"start":    record["slot_start"],
		"end":      record["slot_end"],
	})
}

// 预约核销确认
func VerifyReservationdo(c *gin.Context) {
	currentUser := GetCurrentUser(c)
	if currentUser == nil {
		JsonResponse(c, http.StatusUnauthorized, "请先登录", nil)
		return
	}
	var req struct {
		VerifyCode string `json:"code" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		JsonResponse(c, http.StatusBadRequest, "参数格式错误", nil)
		return
	}
	claims, err := ParseVerificationToken(req.VerifyCode)
	if err != nil {
		JsonResponse(c, http.StatusBadRequest, "核销码无效："+err.Error(), nil)
		return
	}
	var form configs.FormSchema
	if err := configs.DB.First(&form, claims.FormID).Error; err != nil {
		JsonResponse(c, http.StatusNotFound, "表单不存在", nil)
		return
	}
	tx := configs.DB.Begin()
	defer tx.Rollback()
	var record map[string]interface{}
	err = tx.Table(form.TableName).Clauses(clause.Locking{Strength: "UPDATE"}).Where("id = ? AND verification_code = ?", claims.RowID, req.VerifyCode).Scan(&record).Error
	if err != nil {
		JsonResponse(c, http.StatusNotFound, "未找到有效预约记录", nil)
		return
	}
	if used, ok := record["used"].(bool); ok && used {
		JsonResponse(c, http.StatusConflict, "该核销码已被使用", nil)
		return
	}
	updateData := map[string]interface{}{
		"used":        true,
		"used_time":   time.Now(),
		"operator_id": currentUser.ID,
	}
	if err := tx.Table(form.TableName).Where("id = ?", claims.RowID).Updates(updateData).Error; err != nil {
		JsonResponse(c, http.StatusInternalServerError, "核销操作失败", nil)
		return
	}
	if err := tx.Commit().Error; err != nil {
		JsonResponse(c, http.StatusInternalServerError, "系统错误", nil)
		return
	}
	JsonResponse(c, http.StatusOK, "核销成功", gin.H{
		"user":      record["cjz"],
		"date":      record["reservation_date"],
		"time_slot": fmt.Sprintf("%s-%s", record["slot_start"], record["slot_end"]),
		"operator":  currentUser.Name,
	})
}

// 请求参数结构体
type DateQuery struct {
    FormID uint `json:"formId"`
}

type SlotQuery struct {
    FormID uint   `json:"formId"`
    Date   string `json:"date"`
}

// 数据结构
type DateInfo struct {
    Date      string
    Remaining int
}

type SlotInfo struct {
    Start     string
    End       string
    Remaining int
}

// 获取可预约日期接口
func GetAvailableDates(c *gin.Context) {
    currentUser := GetCurrentUser(c)
    if currentUser == nil {
        JsonResponse(c, http.StatusUnauthorized, "请先登录", nil)
        return
    }
    var query DateQuery
    if err := c.ShouldBindJSON(&query); err != nil {
        JsonResponse(c, http.StatusBadRequest, "参数错误", nil)
        return
    }
    var form configs.FormSchema
    if err := configs.DB.First(&form, query.FormID).Error; err != nil {
        JsonResponse(c, http.StatusNotFound, "表单不存在", nil)
        return
    }
    // 解析预约配置
    var rc configs.ReservationConfig
    if err := json.Unmarshal(form.Reservation, &rc); err != nil {
        JsonResponse(c, http.StatusInternalServerError, "预约配置解析失败", nil)
        return
    }
    // 计算可用日期
    dates, err := calculateAvailableDates(rc, form.TableName)
    if err != nil {
        JsonResponse(c, http.StatusInternalServerError, "获取日期失败", nil)
        return
    }
    // 查询用户已预约日期
    var bookedDates []string
    configs.DB.Table(form.TableName).Select("DISTINCT DATE_FORMAT(reservation_date, '%Y-%m-%d') as reservation_date").Where("cjz = ?", currentUser.ID).Pluck("reservation_date", &bookedDates)
    bookedMap := make(map[string]bool)
    for _, d := range bookedDates {
        bookedMap[d] = true
    }
    // 构造响应数据
    result := make([]gin.H, 0)
    for _, date := range dates {
        result = append(result, gin.H{
            "date":      date.Date,
            "display":   formatDisplayDate(date.Date),
            "week":      getWeekday(date.Date),
            "hasBooked": bookedMap[date.Date],
            "remaining": date.Remaining,
        })
    }
    JsonResponse(c, http.StatusOK, "获取成功", result)
}

// 获取时段余量接口
func GetTimeSlots(c *gin.Context) {
    currentUser := GetCurrentUser(c)
    if currentUser == nil {
        JsonResponse(c, http.StatusUnauthorized, "请先登录", nil)
        return
    }
    var query SlotQuery
    if err := c.ShouldBindJSON(&query); err != nil {
        JsonResponse(c, http.StatusBadRequest, "参数错误", nil)
        return
    }
    var form configs.FormSchema
    if err := configs.DB.First(&form, query.FormID).Error; err != nil {
        JsonResponse(c, http.StatusNotFound, "表单不存在", nil)
        return
    }
    // 解析预约配置
    var rc configs.ReservationConfig
    if err := json.Unmarshal(form.Reservation, &rc); err != nil {
        JsonResponse(c, http.StatusInternalServerError, "预约配置解析失败", nil)
        return
    }
    // 计算可用时段
    slots, err := calculateTimeSlots(rc, form.TableName, query.Date)
    if err != nil {
        JsonResponse(c, http.StatusInternalServerError, "获取时段失败", nil)
        return
    }
    // 查询用户已预约时段
    var bookedSlots []string
    configs.DB.Table(form.TableName).Select("slot_start").Where("reservation_date = ? AND cjz = ?", query.Date, currentUser.ID).Pluck("slot_start", &bookedSlots)
    bookedMap := make(map[string]bool)
    for _, s := range bookedSlots {
        bookedMap[s] = true
    }
    // 构造响应数据
    result := make([]gin.H, 0)
    for _, slot := range slots {
        result = append(result, gin.H{
            "start":     slot.Start,
            "end":       slot.End,
            "remaining": slot.Remaining,
            "isBooked":  bookedMap[slot.Start],
        })
    }
    JsonResponse(c, http.StatusOK, "获取成功", result)
}

// 核心计算方法实现
func calculateAvailableDates(rc configs.ReservationConfig, tableName string) ([]DateInfo, error) {
    now := time.Now()
    dates := make([]DateInfo, 0)
    // 解析扩展配置
    var ext configs.ReservationExtensions
    if rc.Extensions != nil {
        if err := json.Unmarshal(rc.Extensions, &ext); err != nil {
            return nil, fmt.Errorf("扩展配置解析失败: %v", err)
        }
    }
    switch rc.Mode {
    case "dynamic":
        for i := 1; i <= rc.MaxDays; i++ {
            date := now.AddDate(0, 0, i)
            dateStr := date.Format("2006-01-02")
            if containsDate(ext.ExcludedDates, dateStr) {
                continue
            }
            // 新增：判断是否是当天
            isTargetToday := dateStr == now.Format("2006-01-02")
            dateTotal := 0
            for _, slot := range rc.TimeSlots {
                // 新增：过滤当天过期时段
                if isTargetToday {
                    // 解析时间段结束时间
                    endTime, err := time.ParseInLocation("15:04", slot.End, time.Local)
                    if err != nil {
                        log.Printf("invalid end time format: %s", slot.End)
                        continue
                    }
                    slotEnd := time.Date(now.Year(), now.Month(), now.Day(), 
                                       endTime.Hour(), endTime.Minute(), 0, 0, time.Local)
                    if now.After(slotEnd) {
                        continue // 跳过过期时段
                    }
                }
                var booked int64
                configs.DB.Table(tableName).Where("reservation_date = ? AND slot_start = ?", 
                    dateStr, slot.Start).Count(&booked)
                dateTotal += slot.MaxPeople - int(booked)
            }
            if dateTotal > 0 {
                dates = append(dates, DateInfo{
                    Date:      dateStr,
                    Remaining: dateTotal,
                })
            }
        }

    case "static":
        // 处理静态配置日期
        for _, d := range rc.AllowedDates {
            if !containsDate(ext.ExcludedDates, d.Date) {
                dates = append(dates, DateInfo{
                    Date:      d.Date,
                    Remaining: calculateDateRemaining(tableName, d.Date, rc.TimeSlots),
                })
            }
        }

    case "custom":
        // 处理自定义配置日期
        for _, d := range rc.AllowedDates {
            if !containsDate(ext.ExcludedDates, d.Date) {
                total := 0
                for _, s := range d.TimeSlots {
                    total += s.MaxPeople
                }
                dates = append(dates, DateInfo{
                    Date:      d.Date,
                    Remaining: calculateDateRemaining(tableName, d.Date, d.TimeSlots),
                })
            }
        }
    }
    return dates, nil
}

func calculateTimeSlots(rc configs.ReservationConfig, tableName string, date string) ([]SlotInfo, error) {
    var timeSlots []configs.TimeSlot
    // 根据模式获取时段配置
    switch rc.Mode {
    case "dynamic", "static":
        timeSlots = rc.TimeSlots
    case "custom":
        for _, d := range rc.AllowedDates {
            if d.Date == date {
                timeSlots = d.TimeSlots
                break
            }
        }
    }
    // 解析目标日期
    targetDate, err := time.ParseInLocation("2006-01-02", date, time.Local)
    if err != nil {
        return nil, fmt.Errorf("invalid date format: %s", date)
    }
    now := time.Now()
    isToday := now.Year() == targetDate.Year() && now.Month() == targetDate.Month() && now.Day() == targetDate.Day()
    slots := make([]SlotInfo, 0)
    for _, ts := range timeSlots {
        var booked int64
        configs.DB.Table(tableName).Where("reservation_date = ? AND slot_start = ?", date, ts.Start).Count(&booked)
        remaining := ts.MaxPeople - int(booked)
        if remaining < 0 {
            remaining = 0
        }
        // 解析时间段的结束时间
        endTime, err := time.ParseInLocation("15:04", ts.End, time.Local)
        if err != nil {
            log.Printf("invalid end time format in time slot: %s", ts.End)
            continue
        }
        slotEnd := time.Date(targetDate.Year(), targetDate.Month(), targetDate.Day(), endTime.Hour(), endTime.Minute(), 0, 0, time.Local)
        // 如果是今天且当前时间已过时段结束时间，跳过该时段
        if isToday && now.After(slotEnd) {
            continue
        }
        slots = append(slots, SlotInfo{
            Start:     ts.Start,
            End:       ts.End,
            Remaining: remaining,
        })
    }
    return slots, nil
}

// 工具函数
func formatDisplayDate(dateStr string) string {
    t, _ := time.Parse("2006-01-02", dateStr)
    return t.Format("01-02")
}

func getWeekday(dateStr string) string {
    t, _ := time.Parse("2006-01-02", dateStr)
    days := []string{"日", "一", "二", "三", "四", "五", "六"}
    return "星期" + days[t.Weekday()]
}

func containsDate(dates []string, target string) bool {
    for _, d := range dates {
        if d == target {
            return true
        }
    }
    return false
}

func calculateDateRemaining(tableName string, date string, slots []configs.TimeSlot) int {
    now := time.Now()
    targetDate, _ := time.Parse("2006-01-02", date)
    isToday := now.Format("2006-01-02") == targetDate.Format("2006-01-02")

    total := 0
    for _, ts := range slots {
        // 新增：过滤当天过期时段
        if isToday {
            endTime, err := time.ParseInLocation("15:04", ts.End, time.Local)
            if err != nil {
                log.Printf("invalid end time: %s", ts.End)
                continue
            }
            slotEnd := time.Date(now.Year(), now.Month(), now.Day(),
                                endTime.Hour(), endTime.Minute(), 0, 0, time.Local)
            if now.After(slotEnd) {
                continue // 跳过过期时段
            }
        }

        var booked int64
        configs.DB.Table(tableName).Where("reservation_date = ? AND slot_start = ?", 
            date, ts.Start).Count(&booked)
        total += ts.MaxPeople - int(booked)
    }
    return total
}

// 执行预约校验
func validateReservation(tx *gorm.DB, bgsx configs.FormSchema, data map[string]interface{}, excludeID uint) (int, string) {
    // 解析预约配置
    var rc configs.ReservationConfig
    if err := json.Unmarshal(bgsx.Reservation, &rc); err != nil {
        return http.StatusInternalServerError, "预约配置解析失败"
    }
    // 获取固定字段值
    date, ok1 := data["reservation_date"].(string)
    start, ok2 := data["slot_start"].(string)
    if !ok1 || !ok2 {
        return http.StatusBadRequest, "缺失预约必要参数：reservation_date 或 slot_start"
    }
    cjzValue, ok := data["cjz"]
    if !ok {
        return http.StatusInternalServerError, "用户身份校验失败"
    }
    var userID uint
    switch v := cjzValue.(type) {
    case int:
        userID = uint(v)
    case float64:
        userID = uint(v)
    case uint:
        userID = v
    case int64:
        userID = uint(v)
    case uint32:
        userID = uint(v)
    default:
        return http.StatusInternalServerError, "用户身份校验失败"
    }
    if userID == 0 {
        return http.StatusBadRequest, "用户身份校验失败"
    }
    // 时段有效性校验
    if err := validateTimeSlot(&rc, date, start); err != nil {
        return http.StatusBadRequest, err.Error()
    }
    // 并发控制校验
    var currentCount int64
    err := tx.Table(bgsx.TableName).Where("reservation_date = ? AND slot_start = ?", date, start).Count(&currentCount).Error
    if err != nil {
        return http.StatusInternalServerError, "预约校验失败：" + err.Error()
    }
    // 获取最大人数
    maxPeople := getMaxPeopleForSlot(&rc, date, start)
    if currentCount >= int64(maxPeople) {
        return http.StatusConflict, fmt.Sprintf("时段 %s 已约满（最大人数 %d）", start, maxPeople)
    }
   // 检查用户是否已预约此时段
    var existingCount int64
    err = tx.Table(bgsx.TableName).Where("reservation_date = ? AND slot_start = ? AND cjz = ?", date, start, userID).Count(&existingCount).Error
    if err != nil {
        return http.StatusInternalServerError, "预约校验失败：" + err.Error()
    }
    if existingCount > 0 {
        return http.StatusInternalServerError, "您已预约过此时段，请勿重复提交"
    }
    // 检查是否允许存在多个未过期预约
    if !rc.AllowMultiple {
        now := time.Now()
        currentDate := now.Format("2006-01-02")
        currentTime := now.Format("15:04")
        var countFuture, countCurrent int64
        // 查询未来日期的预约
        err := tx.Table(bgsx.TableName).Where("cjz = ? AND id != ? AND reservation_date > ?", userID, excludeID, currentDate).Count(&countFuture).Error
        if err != nil {
            return http.StatusInternalServerError, "检查预约记录失败: " + err.Error()
        }
        // 查询当天未过期的预约
        err = tx.Table(bgsx.TableName).Where("cjz = ? AND id != ? AND reservation_date = ? AND slot_end > ?", userID, excludeID, currentDate, currentTime).Count(&countCurrent).Error
        if err != nil {
            return http.StatusInternalServerError, "检查预约记录失败: " + err.Error()
        }
        if total := countFuture + countCurrent; total > 0 {
            return http.StatusConflict, "您已有未过期的预约，无法再次预约"
        }
    }
    return http.StatusOK, ""
}

// 获取时段最大人数（修正后）
func getMaxPeopleForSlot(rc *configs.ReservationConfig, date string, start string) int {
    switch rc.Mode {
    case "dynamic", "static":
        // 处理动态和静态模式
        for _, slot := range rc.TimeSlots {
            if slot.Start == start {
                return slot.MaxPeople
            }
        }
    case "custom":
        // 处理自定义模式，根据日期查找对应配置
        for _, d := range rc.AllowedDates {
            if d.Date == date {
                for _, slot := range d.TimeSlots {
                    if slot.Start == start {
                        return slot.MaxPeople
                    }
                }
            }
        }
    }
    return 0 // 默认不允许
}

// 静态模式日期校验
func isDateAllowed(targetDate string, allowedDates []configs.DateSlot) bool {
    for _, d := range allowedDates {
        if d.Date == targetDate {
            return true
        }
    }
    return false
}

// 动态模式时段校验
func isSlotInDynamicMode(start string, rc *configs.ReservationConfig) bool {
    return isSlotInConfig(start, rc.TimeSlots)
}

// 时段存在性校验
func isSlotInConfig(start string, slots []configs.TimeSlot) bool {
    for _, s := range slots {
        if s.Start == start {
            return true
        }
    }
    return false
}

// 自定义模式时段校验
func isCustomSlotValid(date string, start string, allowedDates []configs.DateSlot) bool {
    for _, d := range allowedDates {
        if d.Date == date {
            for _, s := range d.TimeSlots {
                if s.Start == start {
                    return true
                }
            }
        }
    }
    return false
}

// 校验时段配置有效性
func validateTimeSlot(rc *configs.ReservationConfig, date string, start string) error {
    // 基础日期格式校验
    if _, err := time.Parse("2006-01-02", date); err != nil {
        return fmt.Errorf("日期格式错误，应为YYYY-MM-DD格式")
    }

    // 按模式分流校验
    switch rc.Mode {
    case "dynamic":
        if !isSlotInDynamicMode(start, rc) {
            return fmt.Errorf("当前时段[%s]不可预约", start)
        }
    case "static":
        if !isDateAllowed(date, rc.AllowedDates) {
            return fmt.Errorf("日期[%s]不在可预约范围内", date)
        }
        if !isSlotInConfig(start, rc.TimeSlots) {
            return fmt.Errorf("时段[%s]未配置", start)
        }
    case "custom":
        if !isCustomSlotValid(date, start, rc.AllowedDates) {
            return fmt.Errorf("日期[%s]时段[%s]配置不匹配", date, start)
        }
    default:
        return fmt.Errorf("未知预约模式：%s", rc.Mode)
    }
    return nil
}

// 独立出来的流程处理方法
func createProcessInstance(tx *gorm.DB, bgsx configs.FormSchema, data map[string]interface{}, rowid uint) (bool, int, string) {
    if bgsx.ProcessConfig == nil {
        return true, 0, "" // 无流程配置直接返回成功
    }
    var steps []struct {
        Step       int  `json:"step"`
        ApproverId uint `json:"approverId"`
    }
    if err := json.Unmarshal(bgsx.ProcessConfig, &steps); err != nil {
        return false, http.StatusInternalServerError, "流程配置解析失败"
    }
    if len(steps) == 0 {
        return true, 0, "" // 无审批步骤直接返回成功
    }
    // 创建流程实例
    cjzValue, ok := data["cjz"]
    if !ok {
        return false, http.StatusInternalServerError, "发起人ID不存在"
    }
    var initiatorID uint
    switch v := cjzValue.(type) {
    case int:
        initiatorID = uint(v)
    case float64:
        initiatorID = uint(v)
    case uint:
        initiatorID = v
    case int64:
        initiatorID = uint(v)
    case uint32:
        initiatorID = uint(v)
    default:
        return false, http.StatusInternalServerError, "发起人ID类型错误"
    }
    instance := configs.ProcessInstance{
        FormID:      bgsx.ID,
        DataID:      rowid,
        Status:      "processing",
        CurrentStep: 1,
        InitiatorID: initiatorID,
    }
    if err := tx.Create(&instance).Error; err != nil {
        log.Printf("流程记录创建失败: %v", err)
        return false, http.StatusInternalServerError, "流程实例创建失败"
    }
    // 创建首步骤审批记录
    record := configs.ApprovalRecord{
        InstanceID: instance.ID,
        Step:       1,
        ApproverID: steps[0].ApproverId,
        Status:     "pending",
    }
    if err := tx.Create(&record).Error; err != nil {
        log.Printf("审批记录创建失败: %v", err)
        return false, http.StatusInternalServerError, "审批记录创建失败"
    }
    return true, 0, ""
}

//审批处理接口
func HandleApproval(c *gin.Context) {
    var params struct {
        RecordID uint   `json:"recordId" binding:"required"`
        Result   string `json:"result" binding:"required,oneof=approved rejected"`
        Comment  string `json:"comment"`
    }
    if err := c.ShouldBindJSON(&params); err != nil {
		JsonResponse(c, http.StatusBadRequest, "参数错误", nil)
		return
	}
	currentUser := GetCurrentUser(c) // 获取当前操作者
    // 开启事务
    tx := configs.DB.Begin()
    defer func() {
        if r := recover(); r != nil {
            tx.Rollback()
        }
    }()
    // 1. 更新审批记录
    if err := tx.Model(&configs.ApprovalRecord{}).Where("id = ? AND status = 'pending'", params.RecordID).
        Updates(map[string]interface{}{
            "status": params.Result,
            "comment": params.Comment,
            "approver_id": currentUser.ID,
            "updated_at": time.Now(),
        }).Error; err != nil {
        tx.Rollback()
        JsonResponse(c, http.StatusInternalServerError, "审批状态更新失败", nil)
        return
    }
    // 2. 获取关联流程实例
    var record configs.ApprovalRecord
    if err := tx.First(&record, params.RecordID).Error; err != nil {
        tx.Rollback()
        JsonResponse(c, http.StatusNotFound, "审批记录不存在", nil)
        return
    }
    var instance configs.ProcessInstance
    if err := tx.First(&instance, record.InstanceID).Error; err != nil {
        tx.Rollback()
        JsonResponse(c, http.StatusNotFound, "流程实例不存在", nil)
        return
    }
    // 3. 更新流程状态
    if params.Result == "approved" {
        // 获取流程配置
        var form configs.FormSchema
        if err := tx.First(&form, instance.FormID).Error; err != nil {
            tx.Rollback()
            JsonResponse(c, http.StatusNotFound, "表单配置不存在", nil)
            return
        }
        var steps []struct{ Step int }
        if err := json.Unmarshal(form.ProcessConfig, &steps); err != nil {
            tx.Rollback()
            JsonResponse(c, http.StatusInternalServerError, "流程配置解析失败", nil)
            return
        }
        // 判断是否最后一步
        if instance.CurrentStep >= len(steps) {
            instance.Status = "approved" // 修改最终状态
        } else {
            instance.Status = "processing" // 保持进行中状态
            instance.CurrentStep++
            // 创建下一步审批记录
            //nextStep := steps[instance.CurrentStep-1]
            // 获取下一步审批人
            var nextStepConfig struct {
                ApproverId uint `json:"approverId"`
            }
            found := false
            // 解析完整流程配置
            var processConfig []struct {
                Step            int     `json:"step"`
                ApproverId      uint    `json:"approverId"`
                ApproverName    string  `json:"approverName"` //当前步骤审批人姓名
            }
            if err := json.Unmarshal(form.ProcessConfig, &processConfig); err != nil {
                tx.Rollback()
                JsonResponse(c, http.StatusInternalServerError, "流程配置解析失败", nil)
                return
            }
            // 查找当前步骤对应的审批人
            for _, config := range processConfig {
                if config.Step == instance.CurrentStep {
                    nextStepConfig.ApproverId = config.ApproverId
                    found = true
                    break
                }
            }
            if !found {
                tx.Rollback()
                JsonResponse(c, http.StatusInternalServerError, 
                    fmt.Sprintf("流程配置异常：步骤%d未配置审批人", instance.CurrentStep), 
                    nil)
                return
            }
            if nextStepConfig.ApproverId == 0 {
                tx.Rollback()
                JsonResponse(c, http.StatusInternalServerError,
                    fmt.Sprintf("步骤%d审批人配置无效", instance.CurrentStep),
                    nil)
                return
            }
            // 创建新审批记录
            newRecord := configs.ApprovalRecord{
                InstanceID: instance.ID,
                Step:       instance.CurrentStep,
                ApproverID: nextStepConfig.ApproverId, // 从流程配置获取
                Status:     "pending",
            }
            if err := tx.Create(&newRecord).Error; err != nil {
                tx.Rollback()
                JsonResponse(c, http.StatusInternalServerError, "下一审批步骤创建失败", nil)
                return
            }
        }
    } else {
        instance.Status = "rejected"
    }
    if err := tx.Save(&instance).Error; err != nil {
        tx.Rollback()
        JsonResponse(c, http.StatusInternalServerError, "流程状态更新失败", nil)
        return
    }
    tx.Commit()
    JsonResponse(c, http.StatusOK, "审批处理成功", nil)
}

// 安全流程实例结构体
type SafeProcessInstance struct {
    ID           uint                    `json:"id"`
    CurrentStep  int                     `json:"currentStep"`
    Status       string                  `json:"status"`
    FormSchema   *configs.FormSchema     `json:"formSchema"`
    Initiator    SafeUser                `json:"initiator"`
    ApprovalRecords []SafeApprovalRecord `json:"approvalRecords"`
}

// 安全审批记录结构体
type SafeApprovalRecord struct {
    ID        uint      `json:"id"`
    Step      int       `json:"step"`
    Status    string    `json:"status"`
    Comment   string    `json:"comment"`
    CreatedAt time.Time `json:"createdAt"`
    Approver  SafeUser  `json:"approver"`
}

// 安全用户结构体
type SafeUser struct {
    ID   uint   `json:"id"`
    Name string `json:"name"`
}

// 安全表单结构体（过滤敏感字段）
type SafeFormSchema struct {
    ID        uint   `json:"id"`
    FormName  string `json:"formName"`
    TableName string `json:"tableName"`
    Fields    map[string]interface{} `json:"fields"`
}

//是否存在进行中的流程申请
func CheckApply(c *gin.Context) {
    var params struct {
        FormId uint `json:"formId" binding:"required"`
    }
    if err := c.ShouldBindJSON(&params); err != nil {
        JsonResponse(c, http.StatusBadRequest, "参数错误", nil)
        return
    }
    currentUser := GetCurrentUser(c)
    var (
        process configs.ProcessInstance
        err     error
    )
    // 按角色区分查询逻辑
    if currentUser.Role == "shy" {
        err = configs.DB.
            Preload("FormSchema").
            Preload("ApprovalRecords", func(db *gorm.DB) *gorm.DB {
                return db.Order("step DESC") // 按步骤倒序确保最新记录在前
            }).
            Preload("ApprovalRecords.Approver").
            Preload("Initiator").
            Where("form_id = ? AND status = 'processing'", params.FormId). // 修改状态条件
            First(&process).Error
    } else {
        // 普通用户：查询自己发起的流程
        err = configs.DB.
            Preload("FormSchema").
            Preload("ApprovalRecords.Approver").
            Preload("Initiator").
            Where("form_id = ? AND initiator_id = ? AND status NOT IN ('approved', 'rejected')", params.FormId, currentUser.ID).
            First(&process).Error
    }
    if errors.Is(err, gorm.ErrRecordNotFound) {
        JsonResponse(c, http.StatusOK, "无进行中的流程", nil)
        return
    } else if err != nil {
        JsonResponse(c, http.StatusInternalServerError, "查询失败", nil)
        return
    }
    // 构建安全响应数据
    safeProcess := SafeProcessInstance{
        ID:          process.ID,
        CurrentStep: process.CurrentStep,
        Status:      process.Status,
        FormSchema:  process.FormSchema,
        Initiator: SafeUser{
            ID:   process.Initiator.ID,
            Name: process.Initiator.Name,
        },
        ApprovalRecords: lo.Map(process.ApprovalRecords, func(record configs.ApprovalRecord, _ int) SafeApprovalRecord {
            return SafeApprovalRecord{
                ID:        record.ID,
                Step:      record.Step,
                Status:    record.Status,
                Comment:   record.Comment,
                CreatedAt: record.CreatedAt,
                Approver: SafeUser{
                    ID:   record.Approver.ID,
                    Name: record.Approver.Name,
                },
            }
        }),
    }
    // 获取业务数据
    var formData map[string]interface{}
    if process.FormSchema != nil && process.DataID > 0 {
        tableName := process.FormSchema.TableName
        if err := configs.DB.Table(tableName).Where("id = ?", process.DataID).Scan(&formData).Error; err != nil {
            log.Printf("业务数据查询失败: %v", err)
        }
    }
    JsonResponse(c, http.StatusOK, "存在进行中的流程", map[string]interface{}{
        "process":  safeProcess,
        "formData": formData,
    })
}

// 后台获取流程详情接口
func GetProcessDetail(c *gin.Context) {
    var params struct {
        Rowid uint `json:"rowid" binding:"required"`    // 数据行ID
        FormId uint `json:"formId" binding:"required"`  // 表单ID
    }
    if err := c.ShouldBindJSON(&params); err != nil {
        JsonResponse(c, http.StatusBadRequest, "参数错误", nil)
        return
    }
    var process configs.ProcessInstance
    var err error
    // 查询流程实例
    err = configs.DB.
        Preload("ApprovalRecords", func(db *gorm.DB) *gorm.DB {
            return db.Order("step DESC")  // 按审批步骤倒序排列，确保最新的审批记录在前
        }).
        Preload("ApprovalRecords.Approver").
        Preload("Initiator").
        Where("form_id = ? AND data_id = ?", params.FormId, params.Rowid).  // 使用 formId 和 rowid 进行查询
        First(&process).Error
    if errors.Is(err, gorm.ErrRecordNotFound) {
        JsonResponse(c, http.StatusOK, "未找到相关流程", nil)
        return
    } else if err != nil {
        JsonResponse(c, http.StatusInternalServerError, "查询失败", nil)
        return
    }
    // 构建安全响应数据
    safeProcess := SafeProcessInstance{
        ID:          process.ID,
        CurrentStep: process.CurrentStep,
        Status:      process.Status,
        FormSchema:  nil,
        Initiator: SafeUser{
            ID:   process.Initiator.ID,
            Name: process.Initiator.Name,
        },
        ApprovalRecords: lo.Map(process.ApprovalRecords, func(record configs.ApprovalRecord, _ int) SafeApprovalRecord {
            return SafeApprovalRecord{
                ID:        record.ID,
                Step:      record.Step,
                Status:    record.Status,
                Comment:   record.Comment,
                CreatedAt: record.CreatedAt,
                Approver: SafeUser{
                    ID:   record.Approver.ID,
                    Name: record.Approver.Name,
                },
            }
        }),
    }
    JsonResponse(c, http.StatusOK, "获取流程详情成功",  safeProcess)
}

//审核列表查询：审核员获取待审列表，发起人获取已发起列表（简化版）
func GetTodoList(c *gin.Context) {
    currentUser := GetCurrentUser(c)
    var records []configs.ApprovalRecord
    var instances []configs.ProcessInstance
    var result []map[string]interface{}
    var steps []struct {
        Step            int     `json:"step"`
        ApproverId      uint    `json:"approverId"`
    }
    // 角色区分查询逻辑
    if currentUser.Role == "shy" {
        // 审核员查询（仅待处理任务）
        err := configs.DB.Preload("ProcessInstance.FormSchema").Preload("ProcessInstance.Initiator").Where("approver_id = ?", currentUser.ID).Order("created_at DESC").Find(&records).Error
        if err != nil {
            JsonResponse(c, http.StatusInternalServerError, "查询失败", nil)
            return
        }
        // 构建审核员响应数据
        for _, record := range records {
            // 前置检查
            if record.ProcessInstance == nil || 
               record.ProcessInstance.FormSchema == nil || 
               record.ProcessInstance.FormSchema.ProcessConfig == nil {
                continue
            }
            if err := json.Unmarshal(record.ProcessInstance.FormSchema.ProcessConfig, &steps); err != nil {
                continue
            }
            if record.ProcessInstance == nil || record.ProcessInstance.FormSchema == nil || len(steps) == 0 {
                continue // 跳过无效数据
            }
            result = append(result, map[string]interface{}{
                "type":       "approval",
                "recordId":  record.ID,
                "instanceId": record.ProcessInstance.ID,
                "dataid":  record.ProcessInstance.DataID,
                "formId":  record.ProcessInstance.FormSchema.ID,
                "formName":  record.ProcessInstance.FormSchema.FormName,
                "approverName": record.ProcessInstance.Initiator.Name, //发起人name
                "max":     len(steps), //最大步骤
                "step":      record.Step,
                "status":    record.Status,
                "createdAt": record.CreatedAt.Format(time.RFC3339),
            })
        }
    } else {
        // 发起人查询
        err := configs.DB.Preload("FormSchema").Where("initiator_id = ?", currentUser.ID).Order("created_at DESC").Find(&instances).Error
        if err != nil {
            JsonResponse(c, http.StatusInternalServerError, "查询失败", nil)
            return
        }
        // 构建发起人响应数据
        for _, instance := range instances {
            if err := json.Unmarshal(instance.FormSchema.ProcessConfig, &steps); err != nil {
                continue
            }
            if instance.FormSchema == nil || len(steps) == 0 {
                continue // 跳过无效数据
            }
            result = append(result, map[string]interface{}{
                "type":        "initiated",
                "instanceId": instance.ID,
                "dataid": instance.DataID,
                "formId":  instance.FormSchema.ID,
                "formName":   instance.FormSchema.FormName,
                "approverName": currentUser.Name, //发起人name
                "max":     len(steps), //最大步骤
                "currentStep": instance.CurrentStep,
                "status":      instance.Status,
                "createdAt":  instance.CreatedAt.Format(time.RFC3339),
            })
        }
    }
    JsonResponse(c, http.StatusOK, "获取成功", result)
}

// 转换为JSON字符串
func toJSONString(data map[string]interface{}) string {
    bytes, err := json.Marshal(data)
    if err != nil {
        log.Printf("JSON序列化失败: %v", err)
        return "{}"
    }
    return string(bytes)
}